package com.dp.order.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dp.order.dto.BarCodeExport;
import com.dp.order.dto.ExportOddment;
import com.dp.order.dto.ExportOrder;
import com.dp.order.dto.OutOrder;
import com.dp.order.entity.*;
import com.dp.order.service.*;
import com.dp.order.util.BeanCopyUtil;
import com.dp.order.util.ExportUtil;
import com.dp.order.vo.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @author linzizun
 * @version 1.0
 */
@Slf4j
@AllArgsConstructor
@RestController
@Api(tags = "订单模块接口")
@RequestMapping("/order")
public class OrderController {

    private final OrderService orderService;

    private final CustomerService customerService;

    private final WorkOrderService workOrderService;

    private final BarCodeService barCodeService;

    private final OddmentService oddmentService;

    private final HttpServletResponse httpServletResponse;

    @ApiOperation(value = "输入订单", notes = "输入订单保存到数据库")
    @PostMapping(value = "/createEnterOrder")
    public CommonResult createEnterOrder(@RequestBody List<Order> orderList) {
        Customer customer = customerService.getOne(
                new QueryWrapper<Customer>().eq("account", orderList.get(0).getAccount()));
        if (ObjectUtils.isEmpty(customer)) {
            customer = new Customer();
            customer.setAccount(orderList.get(0).getAccount());
            customerService.save(customer);
        }
        Integer has_order_number = orderService.getBaseMapper().selectCount(new QueryWrapper<Order>().eq("order_number", orderList.get(0).getOrderNumber()));
        if (has_order_number > 0) {
            return new CommonResult(422, "订单已存在");
        }
        boolean result = orderService.saveBatch(orderList);
        if (result) {
            return new CommonResult(200, "插入数据库成功");
        } else {
            return new CommonResult(444, "插入数据库失败");
        }
    }

    @ApiOperation(value = "查询工单", notes = "获取全部未做工单")
    @GetMapping(value = "/getOutOrder")
    public CommonResult getOutOrder(String color, String account) {
        Order order = new Order();
        order.setState(1);
        orderService.update(order, new QueryWrapper<Order>().eq("color", color).eq("state", 0));
        List<OutOrder> outOrderList;
        if (StringUtils.isEmpty(account)) {
            outOrderList = orderService.getOutOrder(color);
        } else {
            outOrderList = orderService.getOrderByAccount(color, account);
        }
        if (null != outOrderList) {
            return new CommonResult(200, "查询数据库成功", outOrderList);
        } else {
            return new CommonResult(444, "查询数据库失败");
        }
    }

    @ApiOperation(value = "修改工单", notes = "根据id修改工单")
    @PutMapping(value = "/updateOrder")
    public CommonResult updateOrder(@RequestBody Order order) {
        boolean result = orderService.updateById(order);
        if (result) {
            return new CommonResult(200, "修改数据库成功");
        } else {
            return new CommonResult(444, "修改数据库失败");
        }
    }

    @ApiOperation(value = "删除工单", notes = "逻辑删除工单")
    @DeleteMapping("/deleteOrder")
    public CommonResult deleteOrder(String id) {
        Order order = new Order();
        order.setId(id);
        order.setHasDelete(1);
        boolean result = orderService.updateById(order);
        if (result) {
            return new CommonResult(200, "删除数据成功");
        } else {
            return new CommonResult(444, "删除数据失败");
        }
    }

    @ApiOperation(value = "导出工单", notes = "导出全部工单")
    @GetMapping(value = "/exportOrder")
    public CommonResult exportOrder(String color) throws IOException {
        // 获取每一根单独的订单信息
        List<OutOrder> outOrderList = orderService.getOutOrder(color);
        if (ObjectUtils.isEmpty(outOrderList)) {
            return new CommonResult(444, "工单已全部导出！");
        }
        List<WorkOrder> workOrderList = new ArrayList<>();
        outOrderList.forEach(outOrder -> {
            for (int i = 0; i < outOrder.getQuantity(); i++) {
                WorkOrder workOrder = new WorkOrder();
                BeanCopyUtil.copy(outOrder, workOrder);
                workOrder.setQuantity(null);
                workOrderList.add(workOrder);
            }
        });
        /*
        // 为余料分配订单
        List<Oddment> oddmentList = oddmentService.list(new QueryWrapper<Oddment>()
                .eq("color", color).eq("has_delete", 0).orderByAsc("clothes_rod_length"));
        oddmentList.forEach(oddment -> {
            List<WorkOrder> answerList = new ArrayList<>();
            int len = ExportUtil.lineUp(workOrderList, answerList, oddment.getClothesRodLength(), 2, 2, 25);
            if(answerList.isEmpty()) {
                return;
            }
            if (oddment.getClothesRodLength() - len > 500) {
                Oddment oddment1 = new Oddment();
                oddment1.setColor(color);
                oddment1.setClothesRodLength(oddment.getClothesRodLength() - len);
                oddment1.setPoleNumber(oddment.getPoleNumber() + "yu");
                oddmentService.save(oddment1);
            }
            answerList.sort(Comparator.comparingInt(WorkOrder::getClothesRodLength));
            StringBuilder barCodeBuilder = new StringBuilder("1#");
            answerList.forEach(workOrder -> {
                workOrder.setId(null);
                workOrder.setQuantity(1);
                workOrder.setPoleNumber(oddment.getPoleNumber());
                barCodeBuilder.append(workOrder.getClothesRodLength()).append("#1#");
            });
            BarCode barCode = new BarCode();
            barCode.setBarCode(barCodeBuilder.toString());
            barCode.setColor(color);
            barCode.setPoleNumber(oddment.getPoleNumber());
            barCodeService.save(barCode);
            workOrderService.saveBatch(answerList);
            oddment.setHasDelete(1);
            oddmentService.updateById(oddment);
        });
        */
        // 分配给新料
        int extent = 5092, accuracy = 50, increment = 10, times = 10;
        String head = "" + LocalDateTime.now().getMinute() + (char) (LocalDateTime.now().getHour() + 65);
        int i = 1;
        while (!workOrderList.isEmpty()) {
            int finalI = i;
            List<WorkOrder> answerList = new ArrayList<>();
            int len = ExportUtil.lineUp(workOrderList, answerList, extent, accuracy, increment, times);
            if (answerList.isEmpty()) {
                continue;
            }
            /*
            if (extent - len > 500) {
                Oddment oddment = new Oddment();
                oddment.setColor(color);
                oddment.setClothesRodLength(extent - len);
                oddment.setPoleNumber(head + finalI + "yu");
                oddmentService.save(oddment);
            }
            */
            answerList.sort(Comparator.comparingInt(WorkOrder::getClothesRodLength));
            // 存入条码
            StringBuilder barCodeBuilder = new StringBuilder("1#");
            answerList.forEach(workOrder -> {
                workOrder.setId(null);
                workOrder.setQuantity(1);
                workOrder.setPoleNumber(head + finalI);
                barCodeBuilder.append(workOrder.getClothesRodLength()).append("#1#");
            });
            BarCode barCode = new BarCode();
            barCode.setBarCode(barCodeBuilder.toString());
            barCode.setColor(color);
            barCode.setPoleNumber(head + finalI);
            barCodeService.save(barCode);
            workOrderService.saveBatch(answerList);
            i++;
        }
        // 逻辑删除数据
        Order order = new Order();
        order.setState(2);
        orderService.update(order, new QueryWrapper<Order>().eq("color", color).eq("state", 1));
        List<ExportOrder> exportOrderList = workOrderService.getExportOrder(color);
        WorkOrder workOrder = new WorkOrder();
        workOrder.setHasDelete(1);
        workOrderService.update(workOrder,
                new QueryWrapper<WorkOrder>().eq("color", color).eq("has_delete", 0));
        // 通过文件流导出文件
        String[] header = {"颜色", "编号", "旺旺号", "长度", "数量", "杆号"};
        String[] fieldNames = ExportUtil.fieldName(ExportOrder.class);
        Workbook wb = ExportUtil.export(header, fieldNames, exportOrderList);
        httpServletResponse.reset();
        String filename = "工单-" + color + "-" + DateTimeFormatter.ofPattern("yyyy_MM_dd HH`mm").format(LocalDateTime.now()) + ".xls";
        httpServletResponse.setContentType("application/msexcel");
        httpServletResponse.setHeader("Content-disposition", "attachment; filename=" +
                new String(filename.getBytes("GBk"), "ISO8859-1"));
        wb.write(httpServletResponse.getOutputStream());
        if (null != exportOrderList) {
            return new CommonResult(200, "查询数据库成功");
        } else {
            return new CommonResult(444, "查询数据库失败");
        }
    }

    @ApiOperation(value = "导出条码", notes = "导出全部条码")
    @GetMapping(value = "/exportBarCode")
    public CommonResult exportBarCode(String color) throws IOException {
        List<BarCode> barCodeList = barCodeService.list(
                new QueryWrapper<BarCode>().eq("color", color).eq("has_delete", 0)
                        .orderByAsc("pole_number"));
        BarCode barCode = new BarCode();
        barCode.setHasDelete(1);
        barCodeService.update(barCode,
                new QueryWrapper<BarCode>().eq("color", color).eq("has_delete", 0));
        List<BarCodeExport> barCodeExportList = new ArrayList<>();
        barCodeList.forEach(barCodeElement -> {
            BarCodeExport barCodeExport = new BarCodeExport();
            BeanCopyUtil.copy(barCodeElement, barCodeExport);
            barCodeExportList.add(barCodeExport);
        });
        Order order = new Order();
        order.setHasDelete(1);
        orderService.update(order,
                new QueryWrapper<Order>().eq("color", color).eq("state", 2));
        // 通过文件流导出文件
        String[] header = {"颜色", "杆号", "条码"};
        String[] fieldNames = ExportUtil.fieldName(BarCodeExport.class);
        Workbook wb = ExportUtil.export(header, fieldNames, barCodeExportList);
        httpServletResponse.reset();
        String filename = "条码表-" + color + "-" + DateTimeFormatter.ofPattern("yyyy_MM_dd HH`mm").format(LocalDateTime.now()) + ".xls";
        httpServletResponse.setContentType("application/msexcel");
        httpServletResponse.setHeader("Content-disposition", "attachment; filename=" +
                new String(filename.getBytes("GBk"), "ISO8859-1"));
        wb.write(httpServletResponse.getOutputStream());
        if (null != barCodeExportList) {
            return new CommonResult(200, "查询数据库成功");
        } else {
            return new CommonResult(444, "查询数据库失败");
        }
    }

    @ApiOperation(value = "获取余料", notes = "获取余料列表")
    @GetMapping("/getOddment")
    public CommonResult getOddment() {
        List<Oddment> oddmentList = oddmentService.list(new QueryWrapper<Oddment>()
                .eq("has_delete", 0)
                .orderByAsc("color"));
        if (null != oddmentList) {
            return new CommonResult(200, "查询数据成功", oddmentList);
        } else {
            return new CommonResult(444, "查询数据失败");
        }
    }

    @ApiOperation(value = "输入余料", notes = "输入余料保存到数据库")
    @PostMapping(value = "/createOddment")
    public CommonResult createOddment(@RequestBody Oddment oddment) {
        boolean result = oddmentService.save(oddment);
        if (result) {
            return new CommonResult(200, "插入数据库成功");
        } else {
            return new CommonResult(444, "插入数据库失败");
        }
    }

    @ApiOperation(value = "导出余料", notes = "导出余料列表")
    @GetMapping("/exportOddment")
    public CommonResult exportOddment() throws IOException {
        List<Oddment> oddmentList = oddmentService.list(
                new QueryWrapper<Oddment>().eq("has_delete", 0)
                        .orderByAsc("color").orderByAsc("pole_number"));
        List<ExportOddment> exportOddmentList = new ArrayList<>();
        oddmentList.forEach(oddment -> {
            ExportOddment exportOddment = new ExportOddment();
            BeanCopyUtil.copy(oddment, exportOddment);
            exportOddmentList.add(exportOddment);
        });
        // 通过文件流导出文件
        String[] header = {"颜色", "衣杆长度", "杆号"};
        String[] fieldNames = ExportUtil.fieldName(ExportOddment.class);
        Workbook wb = ExportUtil.export(header, fieldNames, exportOddmentList);
        httpServletResponse.reset();
        String filename = "余料表-" + DateTimeFormatter.ofPattern("yyyy_MM_dd HH`mm").format(LocalDateTime.now()) + ".xls";
        httpServletResponse.setContentType("application/msexcel");
        httpServletResponse.setHeader("Content-disposition", "attachment; filename=" +
                new String(filename.getBytes("GBk"), "ISO8859-1"));
        wb.write(httpServletResponse.getOutputStream());
        if (null != exportOddmentList) {
            return new CommonResult(200, "查询数据库成功");
        } else {
            return new CommonResult(444, "查询数据库失败");
        }
    }

    @ApiOperation(value = "删除余料", notes = "逻辑删除余料")
    @DeleteMapping("/deleteOddment")
    public CommonResult deleteOddment(String id) {
        Oddment oddment = new Oddment();
        oddment.setId(id);
        oddment.setHasDelete(1);
        boolean result = oddmentService.updateById(oddment);
        if (result) {
            return new CommonResult(200, "删除数据成功");
        } else {
            return new CommonResult(444, "删除数据失败");
        }
    }

    @Scheduled(cron = "0 0 8-17/3 * * ?")//秒 分 时 日 月 星期
    @ApiOperation(value = "清除垃圾数据", notes = "物理清除垃圾数据")
//    @GetMapping(value = "/deleteDate")
    public CommonResult deleteDate(){
        boolean deleteOrder = orderService.remove(new QueryWrapper<Order>().eq("has_delete", 1));
        boolean deleteWorkOrder = workOrderService.remove(new QueryWrapper<WorkOrder>().eq("has_delete", 1));
        boolean deleteBarCode = barCodeService.remove(new QueryWrapper<BarCode>().eq("has_delete", 1));
        boolean deleteOddment = oddmentService.remove(new QueryWrapper<Oddment>().eq("has_delete", 1));
        String result = "{ \"tb_total_order\" : ";
        result += " , \"tb_order\" : ";
        result += deleteOrder ? "true" : "false";
        result += " , \"tb_work_order\" : ";
        result += deleteWorkOrder ? "true" : "false";
        result += " , \"tb_bar_code\" : ";
        result += deleteBarCode ? "true }" : "false";
        result += " , \"tb_oddment\" : ";
        result += deleteOddment ? "true }" : "false }";
        if (deleteOrder || deleteWorkOrder || deleteBarCode || deleteOddment) {
            return new CommonResult(200, "清除垃圾数据成功", result);
        } else {
            return new CommonResult(444, "清除垃圾数据失败");
        }
    }

}
